#include <iostream>
#include <assert.h>

#include <list>

using namespace std;

class Guard {
  public:
    Guard( Mutex &m ) :
	    m_(m) {
	m.acquire();
    }
    ~Guard() {
	m.release();
    }
};

class Stack {
    list< int > store_;
    Mutex m_;
  public:
    Stack() {
    };

    void push( int v ) { 
	Guard g( m_ );
	bool signal = empty();
	store_.push_back( v );
	if ( signal ) {
	    conditional.signal_one();
	}
    }

    int pop( ) {
	Guard g( m_ );
	while ( store_.empty() ) { 
	    Conditional c( m_ ).wait();
	}
	int result = store_.back();
	store_.pop_back();
	return result;
    }
};


int main ( int argc, char *argv[] ) {

    Stack s;
    s.push ( 5 );
    s.push( 4 );

    assert( s.pop() == 4 );
    assert( s.pop() == 5 );
}
